package cn.psvmc.cxzapi.service.store;

import cn.psvmc.cxzapi.config.mybatisplus.service.impl.AbstractService;
import cn.psvmc.cxzapi.exception.ServiceException;
import cn.psvmc.cxzapi.mapper.store.*;
import cn.psvmc.cxzapi.model.common.SearchEntity;
import cn.psvmc.cxzapi.model.store.*;
import cn.psvmc.cxzapi.response.Result;
import cn.psvmc.cxzapi.response.ResultGenerator;
import cn.psvmc.cxzapi.service.alipay.AlipayCreate;
import cn.psvmc.cxzapi.service.system.ServiceUtil;
import cn.psvmc.cxzapi.util.CodeUtil;
import cn.psvmc.cxzapi.util.ToolUtils;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.Synchronized;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 账户表 服务实现类
 * @Author auto
 * @Date 2024-08-14
 */
@Service
public class TAccountService extends AbstractService<TAccountMapper, TAccount> {

    @Resource
    private TAccountMapper tAccountMapper;
    @Resource
    private TAccountRecordMapper accountRecordMapper;
    @Resource
    private TAccountBillMapper accountBillMapper;
    @Resource
    private ServiceUtil serviceUtil;

    /**
    * @Date auto 2024-08-14 更新账户表
    * @Param tAccount 账户表模型
    * @Return int
    */
    @Transactional(rollbackFor = Exception.class)
    @Synchronized
    public Result addBill(TAccountBill bill) {
        Integer accountId = bill.getAccountId();
        // 通过id查询数据处理 详情
        TAccount originTAccount = tAccountMapper.selectById(accountId);
        if (originTAccount == null) {
            throw new ServiceException("未查询到对应的账户表信息！");
        }

        Integer type = bill.getType();
        Double balance = originTAccount.getBalance();
        Double amount = bill.getAmount();
        TAccount tAccount = new TAccount();
        tAccount.setAccountId(accountId);
        double balance2;//交易后金额
        if (type.equals(2)) {//提现
            if (amount.compareTo(balance) > 0) {
                throw new ServiceException("提现金额不能大于余额 ");
            }
            balance2 = ToolUtils.subtract(balance, amount);
        } else {
            balance2 = ToolUtils.add(balance, amount);
        }
        tAccount.setBalance(balance2);
        tAccountMapper.updateByAccountId(tAccount);

        Integer accountType = originTAccount.getAccountType();
        int childType;
        String comm;
        if (accountType.equals(1)) {//租金账户
            if (type.equals(2)) {
                childType = 21;
                comm = "提现";
            } else {
                childType = 11;
                comm = "充值";
            }
        } else {
            if (type.equals(2)) {
                childType = 22;
                comm = "提现";
            } else {
                childType = 12;
                comm = "充值";
            }
        }

        bill.setComm(comm);
        bill.setChildType(childType);
        bill.setInoutType(type);
        bill.setBalance(balance2);
        bill.setStoreid(originTAccount.getStoreid());
        accountBillMapper.insert(bill);

        return ResultGenerator.genSuccessResult("保存成功！");
    }

    /**
     * @Description 账户概览
     * @Date 2024/8/21 22:46
     * @Author YWX
     * @Param [id]
     * @Return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    public List<Map<String, Object>> detail(Integer id) {
        return tAccountMapper.listByStoreId(id);
    }

    /**
     * @Description 提现记录
     * @Date 2024/8/15 22:16
     * @Author YWX
     * @Param [iPage, entity]
     * @Return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map>
     **/
    public IPage<Map> listRecord(Page<TAccount> iPage, SearchEntity entity) {
        serviceUtil.setStoreId(entity);
        return accountRecordMapper.listRecord(iPage, entity);
    }

    /**
     * @Description 记录处理
     * @Date 2024/8/15 22:47
     * @Author YWX
     * @Param [record]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    @Synchronized
    public void handleRecord(TAccountRecord record) {
        TAccountRecord ar = accountRecordMapper.selectById(record.getArid());
        if (ar == null) {
            throw new ServiceException("记录不存在！");
        }
        //已处理不在处理
        if (ar.getStatus().equals(1)) {
            return;
        }
        TAccountBill bill = new TAccountBill();
        bill.setAccountId(ar.getAccountId());
        bill.setAccountType(ar.getAccountType());
        bill.setAmount(ar.getAmount());
        bill.setType(ar.getType());
        bill.setTransactionId(ar.getArid().toString());
        if (ar.getType().equals(2)) {
            String qrCode = AlipayCreate.alipayFundTransUniTransfer(ar.getTransactionId(), ToolUtils.objToString(ar.getAmount()), "提现", ar.getAlipayAccount(), ar.getPayeeName(), "账户提现");
            record.setQrCode(qrCode);
        } else {
            Result result = addBill(bill);
            if (result.getCode() == 0) {
                record.setStatus(1);
            }
        }
        accountRecordMapper.updateById(record);
    }

    /**
     * @Description 添加充值/提现申请
     * @Date 2024/8/15 23:15
     * @Author YWX
     * @Param [record]
     * @Return void
     **/
    @Transactional(rollbackFor = Exception.class)
    @Synchronized
    public String addRecord(TAccountRecord record) {
        String result = "";
        Integer storeId = serviceUtil.getStoreId();
        TAccount account = tAccountMapper.findByAccountTypeAndStoreId(record.getAccountType(), storeId);
        if (account == null) {
            throw new ServiceException("账户不存在！");
        }
        record.setAccountId(account.getAccountId());
        String transactionId = CodeUtil.generateBillSequence();
        record.setTransactionId(transactionId);
        if (record.getType().equals(2)) {//提现
            //获取账户锁定余额和账号信息
            TAccountRecord record1 = accountRecordMapper.findByAccountIdAndStoreId(account.getAccountId(),storeId);
            record.setAlipayAccount(record1.getAlipayAccount());
            record.setPayeeName(record1.getPayeeName());
            if (ToolUtils.isEmpty(record.getAlipayAccount()) || ToolUtils.isEmpty(record.getPayeeName())) {
                throw new ServiceException("收款账号不存在或姓名有误，建议核实账号和姓名是否准确！");
            }
            Double balance = ToolUtils.subtract(account.getBalance(), record1.getAmount());//获取账户可用余额
            Double amount = record.getAmount();
            if (amount.compareTo(balance) > 0) {
                throw new ServiceException("提现金额不能大于余额 ");
            }
        } else {//充值
            result = AlipayCreate.alipayTradePrecreate(transactionId, ToolUtils.objToString(record.getAmount()), "充值");
        }
        record.setAccountType(account.getAccountType());
        record.setStoreid(account.getStoreid());
        record.setQrCode(result);
        accountRecordMapper.insert(record);
        return result;
    }

    /**
     * @Description 收支账单列表
     * @Date 2024/8/21 21:37
     * @Author YWX
     * @Param [queryPage, entity]
     * @Return com.baomidou.mybatisplus.core.metadata.IPage<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    public IPage<Map<String, Object>> listBill(Page<TAccount> queryPage, SearchEntity entity) {
        serviceUtil.setStoreId(entity);
        return accountBillMapper.listBill(queryPage, entity);
    }

    /**
     * @Description 收支账单导出列表
     * @Date 2024/8/21 21:42
     * @Author YWX
     * @Param [entity]
     * @Return java.util.List<java.util.Map<java.lang.String,java.lang.Object>>
     **/
    public List<Map<String, Object>> exportBill(SearchEntity entity) {
        serviceUtil.setStoreId(entity);
        return accountBillMapper.listBill(entity);
    }

    /**
     * @Description 收支概况
     * @Date 2024/8/22 9:18
     * @Author YWX
     * @Param [storeid, date]
     * @Return java.util.Map<java.lang.String,java.lang.Object>
     **/
    public Map<String, Object> overview(Integer storeid, String date) {
        List<Map<String, Object>> list = new ArrayList<>();
        List<TAccountBill> bills = accountBillMapper.listBillByStoreIdAndDate(storeid, date);//指定商户和日期的收支账单列表

        double zjInNum = 0;//租金账户收入
        double zjInAmount = 0;//租金账户支出
        double zjOutNum = 0;//租金账户支出
        double zjOutAmount = 0;//租金账户收入
        double zbjInNum = 0;//质保金账户收入
        double zbjInAmount = 0;//质保金账户支出
        double zbjOutNum = 0;//质保金账户支出
        double zbjOutAmount = 0;//质保金账户收入
        double totalInAmount = 0;//总支出账户收入
        double totalOutAmount = 0;//总收入账户支出

        for (TAccountBill bill : bills) {
            Integer accountType = bill.getAccountType();
            Double amount = bill.getAmount();
            Integer type = bill.getChildType();//交易子类（11租金账户充值 12质保金账户充值 21租金账户提现 22质保金账户提现 30佣金 31租金 32取消订单退款 33订单退款 34账单退款）
            List<Integer> types = Arrays.asList(21, 22, 32, 33, 34);
            if (accountType.equals(1)) {//租金账户
                if (types.contains(type)) {//提现、退款
                    zjOutNum++;
                    zjOutAmount = ToolUtils.add(zjOutAmount, amount);
                    totalOutAmount = ToolUtils.add(totalOutAmount, amount);
                } else {
                    zjInNum++;
                    zjInAmount = ToolUtils.add(zjInAmount, amount);
                    totalInAmount = ToolUtils.add(totalInAmount, amount);
                }
            } else {//质保金账户
                if (types.contains(type)) {//提现、退款
                    zbjOutNum++;
                    zbjOutAmount = ToolUtils.add(zbjOutAmount, amount);
                    totalOutAmount = ToolUtils.add(totalOutAmount, amount);
                } else {
                    zbjInNum++;
                    zbjInAmount = ToolUtils.add(zbjInAmount, amount);
                    totalInAmount = ToolUtils.add(totalInAmount, amount);
                }
            }
        }
        Map<String, Object> zjAccount = new HashMap<>();
        zjAccount.put("name", "租金账户");
        zjAccount.put("inNum", zjInNum);
        zjAccount.put("inAmount", zjInAmount);
        zjAccount.put("outNum", zjOutNum);
        zjAccount.put("outAmount", zjOutAmount);
        list.add(zjAccount);

        Map<String, Object> zbjAccount = new HashMap<>();
        zbjAccount.put("name", "质保金账户");
        zbjAccount.put("inNum", zbjInNum);
        zbjAccount.put("inAmount", zbjInAmount);
        zbjAccount.put("outNum", zbjOutNum);
        zbjAccount.put("outAmount", zbjOutAmount);
        list.add(zbjAccount);
        Map<String, Object> map = new HashMap<>();
        map.put("totalInAmount", totalInAmount);
        map.put("totalOutAmount", totalOutAmount);
        map.put("records", list);
        return map;
    }

    /**
     * @Description 提现申请信息预览
     * @Date 2024/8/22 21:03
     * @Author YWX
     * @Param [entity]
     * @Return java.util.Map
     **/
    public Map preRecord(SearchEntity entity) {
        serviceUtil.setStoreId(entity);
        if (!ToolUtils.isTrueInteger(entity.getStoreid())) {
            throw new ServiceException("商户信息不存在！");
        }
        return accountRecordMapper.preRecord(entity);
    }
}
